/**
 * 
 */
package com.base.common.webservice.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.Map;

/**
 * @author Kat Colin
 *
 */
public class EasyUtils {

	/**
	 * map转换成实体对象
	 * 
	 * @param clazz
	 * @param map
	 * @return
	 */
	public static <T> T mapToObject(Class<?> clazz, Map<String, Object> map) {

		if (null == map) {
			return null;
		}

		// 取得类属性
		Field[] fields = clazz.getFields();
		if (fields.length == 0) {
			fields = clazz.getDeclaredFields();
		}
		Object o = null;
		try {
			o = clazz.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}

		for (Field field : fields) {

			// 取得属性名
			String fieldName = field.getName();

			// 把属性名首字母转成大写
			String strLetter = fieldName.substring(0, 1).toUpperCase();

			// 获得该属性的set方法
			String setterName = "set" + strLetter + fieldName.substring(1);

			Method setMethod = null;

			// 获取属性类型
			Class<?> fieldType = field.getType();

			// 判断类里面是否有改属性的set方法

			if (isHaveSuchMethod(clazz, setterName)) {
				try {
					if (fieldType == String.class) {
						setMethod = clazz.getMethod(setterName, fieldType);
						setMethod.invoke(o, String.valueOf(map.get(fieldName)));// 为其赋值
					} else if (fieldType == Integer.class
							|| fieldType == int.class) {
						setMethod = clazz.getMethod(setterName, fieldType);
						setMethod.invoke(o, Integer.parseInt(String.valueOf(map
								.get(fieldName))));// 为其赋值
					} else if (fieldType == Boolean.class
							|| fieldType == boolean.class) {
						setMethod = clazz.getMethod(setterName, fieldType);
						setMethod.invoke(o, Boolean.getBoolean(String
								.valueOf(map.get(fieldName))));// 为其赋值
					} else if (fieldType == Short.class
							|| fieldType == short.class) {
						setMethod = clazz.getMethod(setterName, fieldType);
						setMethod.invoke(o, Short.parseShort(String.valueOf(map
								.get(fieldName))));// 为其赋值
					} else if (fieldType == Long.class
							|| fieldType == long.class) {
						setMethod = clazz.getMethod(setterName, fieldType);
						setMethod.invoke(o, Long.parseLong(String.valueOf(map
								.get(fieldName))));// 为其赋值
					} else if (fieldType == Double.class
							|| fieldType == double.class) {
						setMethod = clazz.getMethod(setterName, fieldType);
						setMethod.invoke(o, Double.parseDouble(String
								.valueOf(map.get(fieldName))));// 为其赋值
					} else if (fieldType == Float.class
							|| fieldType == float.class) {
						setMethod = clazz.getMethod(setterName, fieldType);
						setMethod.invoke(o, Float.parseFloat(String.valueOf(map
								.get(fieldName))));// 为其赋值
					} else if (fieldType == BigInteger.class) {
						setMethod = clazz.getMethod(setterName, fieldType);
						setMethod
								.invoke(o, BigInteger.valueOf(Long
										.parseLong(String.valueOf(map
												.get(fieldName)))));// 为其赋值
					} else if (fieldType == BigDecimal.class) {
						setMethod = clazz.getMethod(setterName, fieldType);
						setMethod
								.invoke(o, BigDecimal.valueOf(Long
										.parseLong(String.valueOf(map
												.get(fieldName)))));// 为其赋值
					} else if (fieldType == Date.class) {
						setMethod = clazz.getMethod(setterName, fieldType);
						if (map.get(fieldName).getClass() == java.sql.Date.class) {
							setMethod.invoke(
									o,
									new Date(((java.sql.Date) map
											.get(fieldName)).getTime()));// 为其赋值
						} else if (map.get(fieldName).getClass() == java.sql.Time.class) {
							setMethod.invoke(
									o,
									new Date(((java.sql.Time) map
											.get(fieldName)).getTime()));// 为其赋值
						} else if (map.get(fieldName).getClass() == java.sql.Timestamp.class) {
							setMethod.invoke(
									o,
									new Date(((java.sql.Timestamp) map
											.get(fieldName)).getTime()));// 为其赋值
						}
					}
				} catch (NoSuchMethodException e) {
					e.printStackTrace();
				} catch (SecurityException e) {
					e.printStackTrace();
				} catch (NumberFormatException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		}
		return (T) o;
	}

	/**
	 * 判断某个类里是否有某个方法
	 * 
	 * @param clazz
	 * @param methodName
	 * @return
	 */
	public static boolean isHaveSuchMethod(Class<?> clazz, String methodName) {
		Method[] methodArray = clazz.getMethods();
		boolean result = false;
		if (null != methodArray) {
			for (int i = 0; i < methodArray.length; i++) {
				if (methodArray[i].getName().equals(methodName)) {
					result = true;
					break;
				}
			}
		}
		return result;
	}
}
